<template>
  <div ref="mixRef" class="mix-sider-menu-container">
    <ul ref="mixUlRef">
      <li
        v-for="(item, i) in menusRef"
        :key="i"
        :class="parentRoute === item.path ? 'mix-menu-active' : ''"
        class="menu-item"
        @click.stop="setActive(item.path)"
      >
        <span>{{ item.name }}</span>
<!--        <Icon v-if="menuHasChildren(item)" class="has-children" icon="simple-icons:right" />-->
      </li>
    </ul>
    <!-- 控制器 -->
    <div ref="ctrlRef" class="mix-sider-menu-control" @click.stop>
      <div class="btn left-btn" @mouseout.stop="methods.toStop">
        <Icon :size="18" icon="simple-icons:left" @mouseenter="methods.toLeft" />
      </div>
      <div class="btn right-btn" @mouseout.stop="methods.toStop">
        <Icon :size="18" icon="simple-icons:right" @mouseenter="methods.toRight" />
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { ref, onMounted, toRef, onUnmounted } from 'vue';
  import type { Menu } from '/@/router/types';
  import { type RouteLocationNormalized, useRouter } from 'vue-router';
  import { Icon } from '/@/components/Icon';
  import { getCurrentParentPath } from '/@/router/menus';
  import { checkChildrenHidden } from '/@/utils/common/compUtils';
  import { listenerRouteChange } from '/@/logics/mitt/routeChange';
  import { useSplitMenu } from '/@/layouts/default/menu/useLayoutMenu';
  import { MenuSplitTyeEnum } from '/@/enums/menuEnum';

  const mixRef = ref<HTMLDivElement>();
  const mixUlRef = ref<HTMLUListElement>();
  const ctrlRef = ref<HTMLDivElement>();
  var timer: IntervalHandle | null = null;

  const myObserver = new ResizeObserver(() => {
    // 宽度发生了变化
    methods.onControl();
  });

  const currentRoute = ref<Nullable<RouteLocationNormalized>>(null);
  const parentRoute = ref('');
  const $router = useRouter();

  const { menusRef } = useSplitMenu(toRef(MenuSplitTyeEnum.NONE));

  listenerRouteChange(async (route) => {
    currentRoute.value = route;
    parentRoute.value = await getCurrentParentPath(currentRoute.value.path);
  });

  const menuHasChildren = (menuTreeItem: Menu) =>
    !menuTreeItem.meta?.hideChildrenInMenu &&
    Reflect.has(menuTreeItem, 'children') &&
    !!menuTreeItem.children &&
    menuTreeItem.children.length > 0 &&
    checkChildrenHidden(menuTreeItem);

  const setActive = (path: string) => {
    $router.push(path);
  };

  const methods = {
    // 控制器的显示与隐藏
    onControl() {
      if (mixUlRef.value && mixRef.value && ctrlRef.value) {
        const ulWidth = mixUlRef.value.getBoundingClientRect().width + 50; // ul的宽
        const prWidth = mixRef.value.getBoundingClientRect().width; // 父元素的宽
        if (ulWidth > prWidth) {
          ctrlRef.value.style.display = 'flex';
          return true;
        } else {
          ctrlRef.value.style.display = 'none';
          mixUlRef.value.style.left = '0';
          return false;
        }
      }
      return false;
    },
    // 郭碧婷
    toLeft() {
      timer && clearInterval(timer);
      timer = setInterval(() => {
        if (mixUlRef.value && mixRef.value) {
          const isHidden = methods.onControl();
          const parentWidth = mixRef.value.getBoundingClientRect().width - (isHidden ? 50 : 0);
          const ulWidth = mixUlRef.value.getBoundingClientRect().width;
          const ulLeft = mixUlRef.value.getBoundingClientRect().left - mixRef.value.getBoundingClientRect().left;
          const nowLeft = ulLeft > parentWidth - ulWidth ? ulLeft - 1 : ulLeft;
          mixUlRef.value.style.left = nowLeft + 'px';
        }
      });
    },
    // 郭碧晨他的大舅子
    toRight() {
      timer && clearInterval(timer);
      timer = setInterval(() => {
        if (mixUlRef.value && mixRef.value) {
          const ulLeft = mixUlRef.value.getBoundingClientRect().left - mixRef.value.getBoundingClientRect().left;
          const nowLeft = ulLeft < 0 ? ulLeft + 1 : ulLeft;
          mixUlRef.value.style.left = nowLeft + 'px';
        }
      });
    },
    toStop() {
      timer && clearInterval(timer);
    },
  };

  onMounted(() => {
    methods.onControl();
    if (mixRef.value) {
      myObserver.observe(mixRef.value);
    }
  });
  onUnmounted(() => {
    // 清空下防止内存溢出
    if (mixRef.value) {
      myObserver.unobserve(mixRef.value);
      myObserver.disconnect();
    }
  });
</script>

<style lang="less" scoped>
  @controlWidth: 25px;
  .mix-sider-menu-container {
    width: 100%;
    height: 100%;
    overflow: hidden;
    position: relative;
    ul {
      //position: absolute;
      justify-content: center;
      left: 0;
      top: 0;
      display: flex;
      height: 100%;
      overflow: hidden;
      margin-bottom: 0;
      box-sizing: border-box;
      z-index: 1;
      padding-right: @controlWidth * 2;
      .menu-item {
        line-height: 1;
        white-space: nowrap;
        height: 100%;
        padding: 0;
        font-size: 18px;
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 0 20px;
        cursor: pointer;
        .has-children {
          margin-left: 5px;
        }
        &.mix-menu-active {
          color: #1890ff;
        }
      }
    }
    &::after,
    &::before {
      content: '';
      display: block;
      position: absolute;
      z-index: 2;
      width: 20px;
      height: 100%;
      top: 0;
    }
    &::after {
      left: 0;
      background-image: linear-gradient(to right, @sider-dark-bg-color, rgba(0, 0, 0, 0));
    }
    &::before {
      right: @controlWidth * 2;
      background-image: linear-gradient(to left, @sider-dark-bg-color, rgba(0, 0, 0, 0));
    }
    .mix-sider-menu-control {
      position: absolute;
      top: 0;
      right: 0;
      z-index: 2;
      width: @controlWidth * 2;
      height: 100%;
      display: flex;
      .btn {
        background-color: @sider-dark-bg-color;
        width: @controlWidth;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
      }
    }
  }
</style>
